#pragma once

#include "njm_window.hpp"
#include "njm_device.hpp"
#include "njm_swapchain.hpp"
#include <memory>
#include <vector>
#include <cassert>

namespace njm {

    class NjmRenderer
    {
    private:
        NjmWindow& njmWindow;
        NjmDevice& njmDevice;
        std::unique_ptr<NjmSwapChain> njmSwapChain;
        std::vector<VkCommandBuffer> commandBuffers;

        uint32_t currentImageIndex = 0;
        size_t currentFrameIndex = 0;
        bool isFrameStarted = false;

        void createCommandBuffers();
        void freeCommandBuffers();
        void recreateSwapChain();

    public:
        NjmRenderer(NjmWindow& window, NjmDevice& device);
        ~NjmRenderer();
        NjmRenderer(const NjmRenderer&) = delete;
        NjmRenderer &operator=(const NjmRenderer&) = delete;

        VkCommandBuffer beginFrame();
        void endFrame();
        void beginSwapChainRenderPass(VkCommandBuffer commandBuffer);
        void endSwapChainRenderPass(VkCommandBuffer commandBuffer);

        bool isFrameInProgress() const { return isFrameStarted; }
        VkRenderPass getSwapChainRenderPass() const { return njmSwapChain->getRenderPass(); }
        float getAspectRatio() const { return njmSwapChain->extentAspectRatio(); }
        VkCommandBuffer getCurrentCommandBuffer() const {
            assert(isFrameStarted && "can't get commandbuffer if frame not in progress");
            return commandBuffers[currentFrameIndex];
        }
        int getFrameIndex() const { 
            assert(isFrameStarted && "can't get frame index if frame not in progress");
            return currentFrameIndex; 
        }
    };

}
